package com.ld.oauth2.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HTTP工具�?
 * 
 * @author jzj
 */
public class HttpUtil {

	private static Logger log = LoggerFactory.getLogger(HttpUtil.class);

	/** 默认编码方式 -UTF8 */
	private static final String DEFAULT_ENCODE = "utf-8";

	// 信任�?��站点
	static {
		// SSLUtil.trustAllHostnames();
		// SSLUtil.trustAllHttpsCertificates();
	}

	/**
	 * 构�?方法
	 */
	public HttpUtil() {
		// empty constructor for some tools that need an instance object of the
		// class
	}

	/**
	 * GET请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @return 内容字符�?
	 */
	public static String getUrlAsString(String url) throws Exception {
		return getUrlAsString(url, null, DEFAULT_ENCODE);
	}

	/**
	 * GET请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @return 内容字符�?
	 */
	public static String getUrlAsString(String url, Map<String, String> params)
			throws Exception {
		return getUrlAsString(url, params, DEFAULT_ENCODE);
	}

	/**
	 * GET请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @param encode
	 *            编码方式
	 * @return 内容字符�?
	 */
	public static String getUrlAsString(String url, Map<String, String> params,
			String encode) throws Exception {
		// �?��时间
		long t1 = System.currentTimeMillis();
		// 获得HttpGet对象
		HttpGet httpGet = getHttpGet(url, params, encode);
		// 调试信息
		log.debug("url:" + url);
		// log.debug("params:" + params.toString());
		log.debug("encode:" + encode);
		// 发�?请求
		String result = executeHttpRequest(httpGet, null);
		// 结束时间
		long t2 = System.currentTimeMillis();
		// 调试信息
		log.debug("result:" + result);
		log.debug("consume time:" + ((t2 - t1)));
		// 返回结果
		return result;
	}

	/**
	 * POST请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @return 内容字符�?
	 */
	public static String postUrlAsString(String url) throws Exception {
		return postUrlAsString(url, null, null, null);
	}

	/**
	 * POST请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @return 内容字符�?
	 */
	public static String postUrlAsString(String url, Map<String, Object> params)
			throws Exception {
		return postUrlAsString(url, params, null, null);
	}

	/**
	 * POST请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @param reqHeader
	 *            请求头内�?
	 * @return 内容字符�?
	 * @throws Exception
	 */
	public static String postUrlAsString(String url,
			Map<String, Object> params, Map<String, String> reqHeader)
			throws Exception {
		return postUrlAsString(url, params, reqHeader, null);
	}

	/**
	 * POST请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @param reqHeader
	 *            请求头内�?
	 * @param encode
	 *            编码方式
	 * @return 内容字符�?
	 * @throws Exception
	 */
	public static String postUrlAsString(String url,
			Map<String, Object> params, Map<String, String> reqHeader,
			String encode) throws Exception {
		// �?��时间
		long t1 = System.currentTimeMillis();
		// 获得HttpPost对象
		HttpPost httpPost = getHttpPost(url, params, "utf-8");
		// 发�?请求
		String result = executeHttpRequest(httpPost, reqHeader);
		// 结束时间
		long t2 = System.currentTimeMillis();
		// 调试信息
		log.debug("url:" + url);
		log.debug("params:" + params.toString());
		log.debug("reqHeader:" + reqHeader);
		log.debug("encode:" + encode);
		log.debug("result:" + result);
		log.debug("consume time:" + ((t2 - t1)));
		// 返回结果
		return result;
	}

	/**
	 * 获得HttpGet对象
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @param encode
	 *            编码方式
	 * @return HttpGet对象
	 */
	private static HttpGet getHttpGet(String url, Map<String, String> params,
                                      String encode) {
		StringBuffer buf = new StringBuffer(url);
		if (params != null) {
			// 地址增加?或�?&
			String flag = (url.indexOf('?') == -1) ? "?" : "&";
			// 添加参数
			for (String name : params.keySet()) {
				buf.append(flag);
				buf.append(name);
				buf.append("=");
				try {
					String param = params.get(name);
					if (param == null) {
						param = "";
					}
					buf.append(URLEncoder.encode(param, encode));
				} catch (UnsupportedEncodingException e) {
					log.error("URLEncoder Error,encode=" + encode + ",param="
							+ params.get(name), e);
				}
				flag = "&";
			}
		}
		URL url1 = null;

		HttpGet httpGet = new HttpGet(buf.toString());
		return httpGet;
	}

	/**
	 * 获得HttpPost对象
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @param encode
	 *            编码方式
	 * @return HttpPost对象
	 */
	private static HttpPost getHttpPost(String url, Map<String, Object> params,
                                        String encode) {
		HttpPost httpPost = new HttpPost(url);
		if (params != null) {
			List<NameValuePair> form = new ArrayList<NameValuePair>();
			for (String name : params.keySet()) {
				form.add(new BasicNameValuePair(name, params.get(name)
						.toString()));
			}
			try {
				UrlEncodedFormEntity entity = new UrlEncodedFormEntity(form,
						encode);
				httpPost.setEntity(entity);
			} catch (UnsupportedEncodingException e) {
				log.error("UrlEncodedFormEntity Error,encode=" + encode
						+ ",form=" + form, e);
			}
		}
		return httpPost;
	}

	/**
	 * 执行HTTP请求
	 * 
	 * @param request
	 *            请求对象
	 * @param reqHeader
	 *            请求头信�?
	 * @return 内容字符�?
	 */
	@SuppressWarnings({ "deprecation", "resource" })
	private static String executeHttpRequest(HttpUriRequest request,
                                             Map<String, String> reqHeader) throws Exception {
		HttpClient client = null;
		String result = null;
		try {
			// 创建HttpClient对象
			client = new DefaultHttpClient();
			// 设置连接超时时间
			client.getParams().setParameter(
					CoreConnectionPNames.CONNECTION_TIMEOUT, 200000);
			// 设置Socket超时时间
			client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,
					36600);
			// 设置请求头信�?
			if (reqHeader != null) {
				for (String name : reqHeader.keySet()) {
					request.addHeader(name, reqHeader.get(name));
				}
			}
			// 获得返回结果
			HttpResponse response = client.execute(request);
			// 如果成功
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				result = EntityUtils.toString(response.getEntity());
			}
			// 如果失败
			else {
				StringBuffer errorMsg = new StringBuffer();
				errorMsg.append("httpStatus:");
				errorMsg.append(response.getStatusLine().getStatusCode());
				errorMsg.append(response.getStatusLine().getReasonPhrase());
				errorMsg.append(", Header: ");
				Header[] headers = response.getAllHeaders();
				for (Header header : headers) {
					errorMsg.append(header.getName());
					errorMsg.append(":");
					errorMsg.append(header.getValue());
				}
				log.error("HttpResonse Error:" + errorMsg);
			}
		} catch (Exception e) {
			log.error("http连接异常", e);
			throw new Exception("http连接异常");
		} finally {
			try {
				client.getConnectionManager().shutdown();
			} catch (Exception e) {
				log.error("finally HttpClient shutdown error", e);
			}
		}
		return result;
	}

	/**
	 * 下载文件保存到本地
	 * 
	 * @param path
	 *            文件保存位置
	 * @param url
	 *            文件地址
	 * @throws IOException
	 */
	@SuppressWarnings({ "deprecation", "resource" })
	public static void downloadFile(String path, String url,
			Map<String, String> params) throws IOException {
		HttpClient client = null;
		try {
			// 创建HttpClient对象
			client = new DefaultHttpClient();
			// 获得HttpGet对象
			HttpGet httpGet = getHttpGet(url, params, "utf-8");
			// 发送请求获得返回结果
			HttpResponse response = client.execute(httpGet);
			// 如果成功
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				byte[] result = EntityUtils.toByteArray(response.getEntity());
				BufferedOutputStream bw = null;
				try {
					// 创建文件对象
					File f = new File(path);
					log.error("downFile文件夹是否存在========" + f.exists());
					// 创建文件路径
					if (!f.getParentFile().exists())
						f.getParentFile().mkdirs();
					// 写入文件
					bw = new BufferedOutputStream(new FileOutputStream(path));
					bw.write(result);
					bw.flush();
				} catch (Exception e) {
					log.error("保存文件错误,path=" + path + ",url=" + url, e);
				} finally {
					try {
						if (bw != null)
							bw.close();
					} catch (Exception e) {
						log.error(
								"finally BufferedOutputStream shutdown close",
								e);
					}
				}
			}
			// 如果失败
			else {
				StringBuffer errorMsg = new StringBuffer();
				errorMsg.append("httpStatus:");
				errorMsg.append(response.getStatusLine().getStatusCode());
				errorMsg.append(response.getStatusLine().getReasonPhrase());
				errorMsg.append(", Header: ");
				Header[] headers = response.getAllHeaders();
				for (Header header : headers) {
					errorMsg.append(header.getName());
					errorMsg.append(":");
					errorMsg.append(header.getValue());
				}
				log.error("HttpResonse Error:" + errorMsg);
			}
		} catch (ClientProtocolException e) {
			log.error("下载文件保存到本地,http连接异常,path=" + path + ",url=" + url, e);
			throw e;
		} catch (IOException e) {
			log.error("下载文件保存到本地,文件操作异常,path=" + path + ",url=" + url, e);
			throw e;
		} finally {
			try {
				client.getConnectionManager().shutdown();
			} catch (Exception e) {
				log.error("finally HttpClient shutdown error", e);
			}
		}
		log.debug("====================================downloadFile_end===============================================");
	}

	/**
	 * 请求微信api
	 * 
	 * @param urlstr
	 * @return
	 * @throws Exception
	 */
	public static String urlconnect(String urlstr) throws Exception {
		int totallen = 102400;
		char[] sb = new char[totallen];
		URL url = new URL(urlstr);
		URLConnection conn = url.openConnection();
		conn.connect();
		InputStream in = conn.getInputStream();
		InputStreamReader inputStreamReader = new InputStreamReader(in, "UTF-8");
		int len = 0;
		int eachlen = 0;
		while ((eachlen = inputStreamReader.read(sb, len, totallen - len)) > 0) {
			len += eachlen;
		}
		return new String(sb, 0, len);
	}

	public static String getHttpURLConnection(String urls, byte[] b)
			throws Exception {
		String str = "";
		// 需要请求的连接
		URL url = new URL(urls);
		// 打开连接
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		// 设置请求方式和消息头以及超时时间
		conn.setRequestMethod("POST");
		conn.setConnectTimeout(5000);
		// 设置是否允许对外输出数据
		conn.setDoOutput(true);
		conn.setRequestProperty("accept", "*/*");
		conn.setRequestProperty("Content-Type",
				"application/soap+xml; charset=utf-8");
		conn.setRequestProperty("connection", "Keep-Alive");
		conn.setRequestProperty("Content-Length", String.valueOf(b.length));
		// 取得输出流
		OutputStream outPut = conn.getOutputStream();
		outPut.write(b);
		outPut.flush();
		outPut.close();
		// 判断请求是否成功
		if (conn.getResponseCode() == 200) {
			InputStream in = conn.getInputStream();
			byte[] b1 = new byte[999999];
			int len = 0;
			int temp = 0;
			while ((temp = in.read()) != -1) {
				b1[len] = (byte) temp;
				len++;
			}
			str = new String(b1, "UTF-8");
		}
		return str;
	}

	/**
	 * delete请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @return 内容字符??
	 */
	public static String deleteUrlAsString(String url) throws Exception {
		return deleteUrlAsString(url, null, DEFAULT_ENCODE);
	}

	/**
	 * delete请求, 结果以字符串形式返回.
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @param encode
	 *            编码方式
	 * @return 内容字符??
	 */
	public static String deleteUrlAsString(String url,
			Map<String, String> params, String encode) throws Exception {
		// ????时间
		long t1 = System.currentTimeMillis();
		// 获得HttpGet对象
		HttpDelete httpGet = deleteHttpGet(url, params, encode);
		// 调试信息
		log.debug("url:" + url);
		if (params != null) {
			log.debug("params:" + params.toString());
		}
		log.debug("encode:" + encode);
		// 发??请求
		String result = executeHttpRequest(httpGet, null);
		// 结束时间
		long t2 = System.currentTimeMillis();
		// 调试信息
		log.debug("result:" + result);
		log.debug("consume time:" + ((t2 - t1)));
		// 返回结果
		return result;
	}

	/**
	 * 获得HttpDelete对象
	 * 
	 * @param url
	 *            请求地址
	 * @param params
	 *            请求参数
	 * @param encode
	 *            编码方式
	 * @return HttpGet对象
	 */
	private static HttpDelete deleteHttpGet(String url,
                                            Map<String, String> params, String encode) {
		StringBuffer buf = new StringBuffer(url);
		if (params != null) {
			// 地址增加?或??&
			String flag = (url.indexOf('?') == -1) ? "?" : "&";
			// 添加参数
			for (String name : params.keySet()) {
				buf.append(flag);
				buf.append(name);
				buf.append("=");
				try {
					String param = params.get(name);
					if (param == null) {
						param = "";
					}
					buf.append(URLEncoder.encode(param, encode));
				} catch (UnsupportedEncodingException e) {
					log.error("URLEncoder Error,encode=" + encode + ",param="
							+ params.get(name), e);
				}
				flag = "&";
			}
		}
		URL url1 = null;
		HttpDelete httpGet = new HttpDelete(buf.toString());
		return httpGet;
	}


	public void aa() {
		Map<String, String> reqHeader = new HashMap<String, String>();
		reqHeader.put("Content-Type", "multipart/form-data");

		String url = "http://120.77.207.227:7171/slmedia/api/v1/media/send/report";
		Map<String, Object> obj = new HashMap<String, Object>();
		File file = new File("D:\789.png");
		System.out.println(file.exists());
		obj.put("file", file);
		obj.put("msg_type", 2);

		obj.put("from", 37);
		obj.put("from_name", "001");

		obj.put("to", "43");
		obj.put("to_name", "006");

		obj.put("source", "");
		obj.put("source_name", "");
		obj.put("source_flag", 3); // 1固定，2临时，0个人,3调度台
		try {
			System.out.println(obj);
			String str = HttpUtil.postUrlAsString(url, obj);
			System.out.println(str);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void abc() {
		String url = "http://120.77.207.227:9130/Shanli_APP/app/api/videoList.action";

		Map<String, Object> obj = new HashMap<String, Object>();
		obj.put("id", "1");

		try {
			System.out.println(obj);
			String str = HttpUtil.postUrlAsString(url, obj);
			System.out.println(str);
		} catch (Exception e) {
			e.printStackTrace();
		}

		Map<String, String> params = new HashMap<String, String>();
		params.put("filename", "jzj");
		String str = "http://119.254.102.206:9494/upload/e48f62ed-5d65-4602-8b97-e3c4b0a04061.png";
		try {
			downloadFile("E:/aa.png", str, params);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * HTTP PUT请求
	 * 
	 * @param Url
	 * @param parm
	 * @return
	 */
	public static String httpURLConnectionPut(String Url, String parm) {
		try {
			URL url = new URL(Url);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();// 此时cnnection只是为一个连接对象,待连接中
			connection.setDoOutput(true); // 设置连接输出流为true,默认false (post
											// 请求是以流的方式隐式的传递参数)
			connection.setDoInput(true); // 设置连接输入流为true
			connection.setRequestMethod("PUT"); // 设置请求方式为post
			connection.setUseCaches(false); // post请求缓存设为false
			connection.setInstanceFollowRedirects(true); // 设置该HttpURLConnection实例是否自动执行重定向
			connection.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded;charset=utf-8");
			connection.connect(); // 建立连接
			// 创建输入输出流,用于往连接里面输出携带的参数,(输出内容为?后面的内容)
			DataOutputStream dataout = new DataOutputStream(
					connection.getOutputStream());
			dataout.writeBytes(parm);
			// 输出完成后刷新并关闭流
			dataout.flush();
			dataout.close(); // 重要且易忽略步骤 (关闭流,切记!)
			// 连接发起请求,处理服务器响应 (从连接获取到输入流并包装为bufferedReader)
			BufferedReader bf = new BufferedReader(new InputStreamReader(
					connection.getInputStream(), "utf-8"));
			String line;
			StringBuilder sb = new StringBuilder(); // 用来存储响应数据
			// 循环读取流,若不到结尾处
			while ((line = bf.readLine()) != null) {
				sb.append(line).append(System.getProperty("line.separator"));
			}
			bf.close();
			connection.disconnect(); // 销毁连接
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * HTTP put
	 * 
	 * @param url
	 * @param values
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static String doPut(String url, List<NameValuePair> values)
			throws ClientProtocolException, IOException {
		HttpPut request = new HttpPut(url);
		request.setHeader("Accept-Encoding", "gzip, deflate");
		request.setHeader("Accept-Language", "zh-CN");
		request.setHeader("Accept",
				"application/json, application/xml, text/html, text/*, image/*, */*");

		@SuppressWarnings({ "deprecation", "resource" })
        DefaultHttpClient client = new DefaultHttpClient();
		if (values != null && values.size() > 0) {
			try {
				UrlEncodedFormEntity entity;
				entity = new UrlEncodedFormEntity(values);
				request.setEntity(entity);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		HttpResponse response = client.execute(request);
		String resultStr = null;
		if (response != null) {
			// StatusLine statusLine = response.getStatusLine();
			// int statusCode = statusLine.getStatusCode();
			HttpEntity entity = response.getEntity();
			resultStr = EntityUtils.toString(entity);
			// System.out.println(EntityUtils.toString(entity));
			// System.out.println(statusCode);
		}
		return resultStr;
	}

	private static final String APP_KEY = "ld-pc";
	private static final String SECRET_KEY = "ld-secret";

	public static String getAuthenHeader(){
		String auth = APP_KEY + ":" + SECRET_KEY;
		byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(Charset.forName("US-ASCII")));
		String authHeader = "Basic " + new String(encodedAuth);
		return authHeader;
	}


	public static void main(String[] args) throws Exception {
//		String url = "http://120.77.207.227:7171/slmedia/api/v1/media/query/serialnumbers";
//		Map<String, Object> obj = new HashMap<String, Object>();
//		try {
//			for (int i = 0; i < 2; i++) {
//				obj.put("id", String.valueOf(i));
//				String str = HttpUtil.postUrlAsString(url, obj);
//				System.out.println(str);
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
		String authenHeader = getAuthenHeader();
		System.out.println(authenHeader);
		String url = "http://127.0.0.1:8000/oauth/token";
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String, String> reqHeader = new HashMap<String, String>();
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			params.put("grant_type","password");
			params.put("username","admin");
			params.put("password","1234");
			reqHeader.put("Authorization",authenHeader);
			String str = HttpUtil.postUrlAsString(url, params,reqHeader);
			System.out.println(str);
			JSONObject jsonObject = JSON.parseObject(str);
			String access_token = (String) jsonObject.get("access_token");
			String token_type = (String) jsonObject.get("token_type");
			String refresh_token = (String) jsonObject.get("refresh_token");
			Integer expires_in = (Integer) jsonObject.get("expires_in");
			String scope = (String) jsonObject.get("scope");
			String jti = (String) jsonObject.get("jti");
			result.put("access_token",access_token);
			result.put("token_type",token_type);
			result.put("refresh_token",refresh_token);
			result.put("expires_in",expires_in);
			result.put("scope",scope);
			result.put("jti",jti);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}


}
